package com.iplant.wms.serviceImpl.dao.asn;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.annotation.dao.DBBaseDAO;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.wms.service.po.asn.WMSReceiveBillItem;
import com.iplant.wms.service.po.batch.MSSBatchRecord;
import com.iplant.wms.serviceImpl.dao.batch.MSSBatchRecordDAO;
import com.iplant.wms.serviceImpl.dao.wpo.WMSPurchaseOrderItemDAO;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@DBBaseDAO(WMSReceiveBillItem.class)
public class WMSReceiveBillItemDAO extends BaseDAO {


    private static WMSReceiveBillItemDAO Instance = null;

    public static WMSReceiveBillItemDAO getInstance() {
        if (Instance == null) {
            Instance = new WMSReceiveBillItemDAO();
        }
        return Instance;
    }

    private WMSReceiveBillItemDAO() {
        super("");
        this.Init();
    }

    /**
     * 批量保存收货单子项
     *
     * @param wLoginUser
     * @param wItemList
     * @param wErrorCode
     * @return
     */
    public void WMS_UpdateReceiveBillItemList(BMSEmployee wLoginUser, List<WMSReceiveBillItem> wItemList, OutResult<Integer> wErrorCode) {

        try {
            wErrorCode.set(0);

            if (wItemList.isEmpty()) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
            }

            for (WMSReceiveBillItem wItem : wItemList) {
                this.WMS_UpdateReceiveBillItem(wLoginUser, wItem, wErrorCode);
                if (wErrorCode.Result != 0) {
                    break;
                }
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }
    }

    /**
     * 添加或修改
     *
     * @param wLoginUser
     * @param wItem
     * @param wErrorCode
     * @return
     */
    public Integer WMS_UpdateReceiveBillItem(BMSEmployee wLoginUser, WMSReceiveBillItem wItem, OutResult<Integer> wErrorCode) {
        Integer wResult = 0;

        try {
            if (wItem == null) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }

            if (StringUtils.isNotEmpty(wItem.BatchRuleCode)) {
                // 批次信息的新增或更新
                MSSBatchRecord wBatchRecord = new MSSBatchRecord();
                wBatchRecord.ID = wItem.BatchRecordID;
                wBatchRecord.Code = wItem.BatchRecordCode;
                wBatchRecord.ProductDate = wItem.ProductDate;
                wBatchRecord.ExpireDate = wItem.ExpireDate;
                wBatchRecord.StockDate = wItem.StockDate;
                wBatchRecord.LotAttr04 = wItem.LotAttr04;
                wBatchRecord.LotAttr05 = wItem.LotAttr05;
                wBatchRecord.LotAttr06 = wItem.LotAttr06;
                wBatchRecord.LotAttr07 = wItem.LotAttr07;
                wBatchRecord.LotAttr08 = wItem.LotAttr08;
                wBatchRecord.LotAttr09 = wItem.LotAttr09;
                wBatchRecord.LotAttr10 = wItem.LotAttr10;
                wBatchRecord.LotAttr11 = wItem.LotAttr11;
                wBatchRecord.LotAttr12 = wItem.LotAttr12;

                wBatchRecord.FactoryID = wItem.FactoryID;
                wBatchRecord.FactoryCode = wItem.FactoryCode;
                wBatchRecord.FactoryName = wItem.FactoryName;
                wBatchRecord.CustomerID = wItem.SupplierID;
                ; // 注意不同业务采用CustomerID or SupplierID
                wBatchRecord.CustomerCode = wItem.SupplierCode;
                wBatchRecord.CustomerName = wItem.SupplierName;

                wBatchRecord.MaterialID = wItem.MaterialID;
                wBatchRecord.MaterialNo = wItem.MaterialCode;
                wBatchRecord.MaterialName = wItem.MaterialName;

                wBatchRecord.RuleCode = wItem.BatchRuleCode;
                if (wBatchRecord.ProductDate == null) {
                    wBatchRecord.ProductDate = Calendar.getInstance();
                }
                if (wBatchRecord.ExpireDate == null) {
                    wBatchRecord.ExpireDate = CalendarTool.AddCalendar(Calendar.getInstance(), Calendar.YEAR, 10);
                }
                if (wBatchRecord.StockDate == null) {
                    wBatchRecord.StockDate = Calendar.getInstance();
                }


                MSSBatchRecordDAO.getInstance().UpdatePo(wLoginUser, wBatchRecord, wErrorCode);

                if (wErrorCode.Result != 0) {
                    return wResult;
                }
                if (wItem.BatchRecordID <= 0) {
                    wItem.BatchRecordID = wBatchRecord.ID;
                }
            }

            wItem.setUserInfo(wLoginUser);
            wResult = this.UpdatePo(wLoginUser, wItem, wErrorCode);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }

        return wResult;
    }


    public void WMS_DeleteReceiveBillItemListByArrivalNoticeID(BMSEmployee wLoginUser,
                                                               int wArrivalNoticeID, OutResult<Integer> wErrorCode) {
        try {
            if (wArrivalNoticeID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("ArrivalNoticeID", wArrivalNoticeID);

            this.Delete(wParams, " and ID>0");
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }
    }

    public void WMS_DeleteReceiveBillItemListByArrivalNoticeItemID(BMSEmployee wLoginUser,
                                                                   int wArrivalNoticeItemID, OutResult<Integer> wErrorCode) {
        try {
            if (wArrivalNoticeItemID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("ArrivalNoticeItemID", wArrivalNoticeItemID);

            this.Delete(wParams, " and ID>0");
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }
    }

    public void WMS_DeleteReceiveBillItemListByArrivalNoticeItemIDList(BMSEmployee
                                                                               wLoginUser, List<Integer> wArrivalNoticeItemIDList, OutResult<Integer> wErrorCode) {
        try {
            if (wArrivalNoticeItemIDList == null || wArrivalNoticeItemIDList.size() == 0) {
                return;
            }
            Map<String, Object> wParams = new HashMap<>();
            this.Delete(StringUtils.Format("ArrivalNoticeItemID in ()",
                    StringUtils.Join(",", wArrivalNoticeItemIDList)), " and ID>0 ");
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }
    }


    /**
     * 用母单ID查子项
     *
     * @param wLoginUser
     * @param wReceiveBill
     * @param wPagination
     * @param wErrorCode
     * @return
     */
    public List<WMSReceiveBillItem> WMS_SelectListByReceiveBillID(BMSEmployee wLoginUser,
                                                                  int wReceiveBill, Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<WMSReceiveBillItem> wResultList = new ArrayList<>();

        try {
            if (wReceiveBill <= 0) {

                return wResultList;
            }
            Map<String, Object> wParams = new HashMap<>();

            wParams.put("ReceiveBillID", wReceiveBill);

            wResultList = SelectPOList(wLoginUser, wParams, wPagination, wErrorCode);
        } catch (Exception ex) {
            wErrorCode.set(Integer.valueOf(ExceptionTypes.DBSQL.getValue()));
            log.error(ex.toString());
        }

        return wResultList;
    }


    public void WMS_UpdateReceiveBillItemFQTY(BMSEmployee
                                                      wLoginUser, List<Integer> wIDList, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);
        try {
            String wSQLText = StringUtils.Format("update {0} t set t.StockFQTY= " +
                            "( select ifnull( sum(t2.FQTY),0) from {1} t2 WHERE t2.StoreStationID>0 and t2.StockOperateRecordID>0 and t.ID=t2.SalesDeliveryItemID) where  t.ID IN (2) ",
                    this.getTableName(), this.getTableName("wms_outboundorderitem"), StringUtils.Join(",", wIDList));

            this.Update(wSQLText, new HashMap<>());

            List<WMSReceiveBillItem> wList = this.SelectPOList(wLoginUser, wIDList, Pagination.getMaxSize(WMSReceiveBillItem.class), wErrorCode);
            if (wErrorCode.Result != 0)
                return;


            List<Integer> wASNItemIDList = wList.stream().map(p -> p.ArrivalNoticeItemID).distinct().collect(Collectors.toList());

            WMSArrivalNoticeItemDAO.getInstance().WMS_UpdateArrivalNoticeFQTY(wLoginUser, wASNItemIDList, wErrorCode);
            if (wErrorCode.Result != 0)
                return;
            List<Integer> wPOItemIDList = wList.stream().map(p -> p.PurchaseOrderItemID).distinct().collect(Collectors.toList());

            wPOItemIDList.removeIf(p -> p <= 0);
            if (wPOItemIDList.size() > 0) {
                WMSPurchaseOrderItemDAO.getInstance().WMS_UpdatePurchaseOrderFQTY(wLoginUser, wPOItemIDList, wErrorCode);
                if (wErrorCode.Result != 0)
                    return;
            }

        } catch (Exception e) {
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
            log.error("WMS_UpdateReceiveBillItemFQTY", e);
        }
    }
}
